package utils;

import cn.shopping.common.exception.CommonException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 描述:
 *
 * @author Zhanggq
 * @date 2019/4/8 14:02
 */
public class StringUtils {
    private static final String TAG = "StringUtils";

    /**
     * Returns true if the string is null or 0-length.
     *
     * @param str the string to be examined
     * @return true if str is null or zero length
     */
    public static boolean isEmpty(String str) {
        if(str==null){
            return true;
        }else{
            str = str.replaceAll("　","");
            if(str.trim().length()==0){
                return true;
            }else{
                return false;
            }
        }
    }

    /**
     * Returns true if a and b are equal, including if they are both null.
     * <p><i>Note: In platform versions 1.1 and earlier, this method only worked well if
     * both the arguments were instances of String.</i></p>
     *
     * @param a first CharSequence to check
     * @param b second CharSequence to check
     * @return true if a and b are equal
     */
    public static boolean equals(CharSequence a, CharSequence b) {
        if (a == b) return true;
        int length;
        if (a != null && b != null && (length = a.length()) == b.length()) {
            if (a instanceof String && b instanceof String) {
                return a.equals(b);
            } else {
                for (int i = 0; i < length; i++) {
                    if (a.charAt(i) != b.charAt(i)) return false;
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 生成MD5
     */
    public static String getMD5(String source) {
        return getMD5(source.getBytes());
    }

    /**
     * 生成MD5
     */
    public static String getMD5(byte[] source) {
        String s = null;
        // 用来将字节转换成 16 进制表示的字符
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            MessageDigest md = MessageDigest
                    .getInstance("MD5");
            md.update(source);

            /*
             *  MD5 的计算结果是一个 128 位的长整数，用字节表示就是 16 个字节，
             *  每个字节用 16 进制表示的话，使用两个字符，所以表示成 16 进制需要 32 个字符。
             *  不采用String.format进行格式化，String.format比较慢，慢差不多50倍。
             */
            byte tmp[] = md.digest();

            char str[] = new char[16 * 2];

            int k = 0;
            for (int i = 0; i < 16; i++) {
                // 从第一个字节开始，对 MD5 的每一个字节
                // 转换成 16 进制字符的转换
                byte byte0 = tmp[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            s = new String(str);

        } catch (Exception e) {
            throw CommonException.exception("字符串转换失败！");
        }
        return s;
    }

    /**
     * url List 转成存数据库的String字段
     *
     * @param urls
     * @return
     */
    public static String urlsToString(List<String> urls) {
        StringBuffer sb = new StringBuffer();
        if (null != urls && urls.size() > 0) {
            for (String url : urls) {
                sb.append(url + ";");
            }
        }
        return sb.toString();
    }



    /**
     * 数据库内读出来的urls转换成list
     *
     * @param urlString
     * @return
     */
    public static List<String> stringToUrls(String urlString) {
        List<String> list = new ArrayList<>();
        if (null != urlString) {
            String[] urls = urlString.split(";");
            for (String url : urls) {
                if (null != urls && urls.length > 0) {
                    list.add(url);
                }
            }
        }
        return list;
    }

    /**
     * 是否是电话号码
     * @param input
     * @return
     */
    public static boolean matchPhoneNumber(String input) {
        // 电话号码正则表达式
        final String PHONEURL_STRING = "((?<=\\D|^)((\\d{7,13})|((\\d{3,4}-)?\\d{7,8}))(?=\\D|$))";
        final Pattern patternPhoneNumber = Pattern.compile(PHONEURL_STRING, Pattern.CASE_INSENSITIVE);
        final Matcher matcher = patternPhoneNumber.matcher(input);
        return matcher.matches();
    }

    /**
     * 自动生成32位的UUid，对应数据库的主键id进行插入用。
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 创建指定数量的随机字符串
     *
     * @param numberFlag 是否是数字
     * @param length
     * @return
     */
    public static String createRandom(boolean numberFlag, int length) {
        String retStr = "";
        String strTable = numberFlag ? "1234567890" : "1234567890abcdefghijkmnpqrstuvwxyz";
        int len = strTable.length();
        boolean bDone = true;
        do {
            retStr = "";
            int count = 0;
            for (int i = 0; i < length; i++) {
                double dblR = Math.random() * len;
                int intR = (int) Math.floor(dblR);
                char c = strTable.charAt(intR);
                if (('0' <= c) && (c <= '9')) {
                    count++;
                }
                retStr += strTable.charAt(intR);
            }
            if (count >= 2) {
                bDone = false;
            }
        } while (bDone);
        return retStr;
    }

    /**
     * base64加密
     * @param str
     * @return
     */
    public static String base64Encode(String str) {
        byte[] b = null;
        String s = null;
        try {
            b = str.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            throw CommonException.exception("读取字符串失败！");
        }
        if (b != null) {
            s = new BASE64Encoder().encode(b);
        }
        return s;
    }

    /**
     * base64解密
     * @param s
     * @return
     */
    public static String base64Decode(String s) {
        byte[] b = null;
        String result = null;
        if (s != null) {
            BASE64Decoder decoder = new BASE64Decoder();
            try {
                b = decoder.decodeBuffer(s);
                result = new String(b, "utf-8");
            } catch (Exception e) {
                throw CommonException.exception("解密失败！");
            }
        }
        return result;
    }

    /**
     * 是否是数字
     * @param str
     * @return boolean
     */
    public static boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("^-?[0-9]+");
        Matcher isNum = pattern.matcher(str);
        if(!isNum.matches() ){
            return false;
        }
        return true;
        //return !isEmpty(str) && org.codehaus.plexus.util.StringUtils.isNumeric(str);
    }


    /**
     * 如果为null则返回0
     * @param str
     * @return
     */
    public static String removeNullToZero(Object str){
        return (str != null&&!str.equals("")&&!str.equals(" ")) ? str.toString() : "0";
    }


    public static String removeNull(Object str) {
        return (str != null) ? str.toString() : "";
    }

    public static boolean isNullOrEmpty(Object o) {
        return (o == null) || (String.valueOf(o).trim().length() == 0);
    }

    public static boolean isNotEmpty(CharSequence cs) {
        return !isEmpty(cs);
    }
    public static boolean isEmpty(CharSequence cs) {
        return cs == null || cs.length() == 0;
    }


    public static String calcPercent(int total, int calc){
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        if(total==0 || calc==0){
            return  "0%";
        }
        return  numberFormat.format((float) calc / (float) total * 100) +"%" ;
    }

    /**
     * 截取字符串分隔符后的字符
     * <pre>
     *     例如 字符串为"hyzs",分割符为"hy",则返回结果为"zs"
     * </pre>
     * @param str
     * @param separator 分隔符
     * @return
     */
    public static String substringAfterLast(String str, String separator) {
        if(isEmpty(str)) {
            return str;
        } else if(isEmpty(separator)) {
            return "";
        } else {
            int pos = str.lastIndexOf(separator);
            return pos != -1 && pos != str.length() - separator.length()?str.substring(pos + separator.length()):"";
        }
    }

   /* public static void main(String[] args) {
        System.out.println(substringAfterLast("hyzs", "hy"));
    }*/

}

